﻿using Mapster;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Nacos.AspNetCore.V2;
using Nacos.V2;
using Nacos.V2.DependencyInjection;
using System.Runtime.InteropServices;
using XYS.Core.Models;

namespace XYS.Service.Core
{
    /// <summary>
    /// 配置中心
    /// </summary>
    public static class ConfigurationCenterExtension
    {
        /// <summary>
        /// 
        /// </summary>
        public static NacosAspNetOptions nacosSetting;
        /// <summary>
        /// 添加配置中心
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="logger"></param>
        /// <returns></returns>
        public static WebApplicationBuilder AddConfigurationCenter(this WebApplicationBuilder builder, ILogger logger)
        {
            string settingFile = $"appsettings.{GlobalCoreSetting.EnvironmentName}.json";

            if (File.Exists(settingFile))
            {
                logger.LogInformation($"加载配置文件<{settingFile}>");
                builder.Configuration.AddJsonFile(settingFile);
            }
            //获取 服务名字
            GlobalCoreSetting.ServiceName = builder.Configuration["ServiceName"];

            //获取默认的nacos配置
            nacosSetting = builder.Configuration.GetSection("nacos").Get<NacosAspNetOptions>();
            OnAppBuilderAction.ConfigurationCenteringAction?.Invoke(builder, nacosSetting);
            if (nacosSetting != null)
            {
                logger.Log(LogLevel.Information, $"注册 Nacos 服务发现");
                //添加 nacos 配置
                builder.Host.UseNacosConfig(section: "nacos", parser: Nacos.YamlParser.YamlConfigurationStringParser.Instance, loggingBuilder =>
                {
                    loggingBuilder.ClearProviders();
                    loggingBuilder.AddConsole();
                });

                string nacosIp = builder.Configuration["NACOS_IP"];
                string nacosPortString = builder.Configuration["NACOS_PORT"];
                string nacosWeightString = builder.Configuration["NACOS_WEIGHT"];
                if (!string.IsNullOrEmpty(nacosIp) && !string.IsNullOrEmpty(nacosPortString) && !string.IsNullOrEmpty(nacosWeightString))
                {
                    logger.Log(LogLevel.Information, @$"使用自定义服务发现配置
NACOS_IP:{nacosIp}
NACOS_PORT:{nacosPortString}
NACOS_WEIGHT:{nacosWeightString}");

                    if (!int.TryParse(nacosPortString, out int nacosPort))
                    {
                        logger.Log(LogLevel.Information, $"自定义服务发现配置[NACOS_PORT]，端口配置错误");
                        throw new Exception($"自定义服务发现配置[NACOS_PORT]，端口配置错误");
                    }

                    if (!double.TryParse(nacosWeightString, out double nacosWeight))
                    {
                        logger.Log(LogLevel.Information, $"自定义服务发现配置[NACOS_WEIGHT]，权重配置错误");
                        throw new Exception($"自定义服务发现配置[NACOS_WEIGHT]，权重配置错误");
                    }

                    if (nacosSetting == null)
                    {
                        logger.Log(LogLevel.Information, $"nacos 配置获取失败");
                        throw new Exception($"nacos 配置获取失败");
                    }
                    nacosSetting.Ip = nacosIp;
                    nacosSetting.Port = nacosPort;
                    nacosSetting.Weight = nacosWeight;

                    //如果 权重小于等于0，则直接不注册服务
                    nacosSetting.RegisterEnabled = false;
                    nacosSetting.InstanceEnabled = false;
                    builder.Services.AddNacosAspNet(optionsAccs => nacosSetting.Adapt(optionsAccs));

                    if (nacosWeight > 0)
                    {
                        // 获取 Nacos 客户端实例
                        var nacosNamingService = builder.Services.BuildServiceProvider().GetRequiredService<INacosNamingService>();

                        // 注册 HTTP 实例
                        var httpInstance = new Nacos.V2.Naming.Dtos.Instance
                        {
                            Ip = nacosSetting.Ip,
                            Port = nacosSetting.Port,
                            Weight = nacosWeight,
                            Metadata = new Dictionary<string, string>
                            {
                                [NacosMetadataKeys.Protocol] = NacosMetadataKeys.Http,
                                [NacosMetadataKeys.DotnetVersion] = RuntimeInformation.FrameworkDescription
                            }
                        };
                        // 注册 HTTP 实例
                        nacosNamingService.RegisterInstance(nacosSetting.ServiceName, httpInstance);
                    }
                }
                else
                {
                    //nacos服务注册
                    builder.Services.AddNacosAspNet(builder.Configuration, section: "nacos");
                }

                if (File.Exists(settingFile))
                {
                    logger.LogInformation($"加载配置文件<{settingFile}>");
                    builder.Configuration.AddJsonFile(settingFile);
                }
            }

            var loadAppsettingsLocalJsonString = builder.Configuration["LoadAppsettingsLocalJson"];
            logger.LogInformation($"LoadAppsettingsLocalJson：{loadAppsettingsLocalJsonString}");
            if ((loadAppsettingsLocalJsonString == "1" || (bool.TryParse(loadAppsettingsLocalJsonString, out var loadAppsettingsLocalJson) && loadAppsettingsLocalJson))
                && File.Exists("appsettings.local.json"))
            {
                logger.LogInformation($"加载配置文件<appsettings.local.json>");
                builder.Configuration.AddJsonFile("appsettings.local.json");
            }

            //设置更新周期
            Nacos.V2.Naming.Core.ServiceInfoUpdateService.UpdateDeayTime = Math.Max(GlobalCoreSetting.UpdateDeayTime.Milliseconds, 1000);

            OnAppBuilderAction.ConfigurationCenteredAction?.Invoke(builder, nacosSetting);
            return builder;
        }
    }
}
